/*****************************************************************************/ /*!
* file  : systask.c
* creat : apleilx
* note :  除初始化外，禁止该任务及其子程序使用含有阻塞的功能，包括数据存储，USB操作等等
* data  : 2019/07/02
*******************************************************************************/
#include "common.h"

#include "bsp_api.h"
#include "bsp_spi_nor.h"
#include "nor_cmd.h"

#include "nand_lut.h"
#include "nand_w25n.h"

#include "swap.h"

#include "fat_file_opt.h"
#include "simp_fat_update.h"

/*****************************************************************************
* @brief   const define
*****************************************************************************/
#define NAND_BLOCK_SITE_FILE 16

/*****************************************************************************
* @brief   function
*****************************************************************************/
uint8_t nand_get_blk_dat(uint32_t addr_offset, uint8_t *pdat, uint16_t len);

/*****************************************************************************
* @brief   simp_fat_tab_erase.
* @param   none
* @return  none
*****************************************************************************/
void simp_fat_tab_erase(void)
{
    switch (efat.fsel)
    {
    case 0:
        nor_sector_erase(0);
        nor_sector_erase(0 + 0x1000);
        nor_sector_erase(0 + 0x2000);
        nor_sector_erase(0 + 0x3000);
        break;

    default:
        break;
    }
}

/*****************************************************************************
* @brief   simp_fat_tab_write.
* @param   none
* @return  none
*****************************************************************************/
void simp_fat_tab_write(uint32_t addr_offset, uint8_t *buff, uint32_t len)
{
    switch (efat.fsel)
    {
    case 0:
        nor_write_multi(0 + addr_offset, len, buff);
        break;

    default:
        break;
    }
}

/*****************************************************************************
* @brief   simp_fat_tab_save.
* @param   none
* @return  none
*****************************************************************************/
void simp_fat_tab_save(void)
{
    switch (efat.fsel)
    {
    case 0:
        break;

    default:
        break;
    }
}

/*****************************************************************************
* @brief   simp_fat_main_write_start.
* @param   none
* @return  none
*****************************************************************************/
void simp_fat_main_write_start(void)
{
    uint8_t falsh_st;

    switch (efat.fsel)
    {
    case 0:
    {
        // flash write enable
        spi_nand_write_enable();
        falsh_st = spi_nand_featute_get(NAND_FEATURE_1_PROTECT); //测试读取的默认值是0x7C
        flash_dbg_print("read nand reg1 = 0x%02X\n", falsh_st);
        if (falsh_st != 0)
        {
            flash_dbg_print("nand set reg1 to 0x00\n");
            spi_nand_write_enable();
            spi_nand_featute_set(NAND_FEATURE_1_PROTECT, 0xFF, 0);
            falsh_st = spi_nand_featute_get(NAND_FEATURE_1_PROTECT);
            flash_dbg_print("read nand reg1 = 0x%02X\n", falsh_st);
        }
    }
    break;

    default:
        break;
    }
}

/*****************************************************************************
* @brief   simp_fat_main_write_start.
* @param   none
* @return  none
*****************************************************************************/
void simp_fat_main_write_end(void)
{
    switch (efat.fsel)
    {
    case 0:
        // flash write disable
        spi_nand_write_disable();
        break;

    default:
        break;
    }
}

/*****************************************************************************
* @brief   simp_fat_main_write_start.
* @param   none
* @return  none
*****************************************************************************/
void simp_fat_main_write(uint32_t block)
{
    switch (efat.fsel)
    {
    case 0:
        nand_lut_block_write(block + NAND_BLOCK_SITE_FILE, nand_get_blk_dat);
        break;

    default:
        break;
    }
}

/*****************************************************************************
* @brief   nand_get_blk_dat
* @param   addr pdat len
* @return  non
*****************************************************************************/
uint8_t nand_get_blk_dat(uint32_t addr_offset, uint8_t *pdat, uint16_t len)
{
    UINT len_back;
    int fil_site = efat.wr_fil_block * efat.wr_block_size + addr_offset;

    // 读取文件
    if (fil_site < efat.main_len)
    {
        // 文件定位-仅在回写时重新定位
        if (fil_site < efat.wr_site_old)
        {
            fat_fil_seek(efat.fil, fil_site + efat.main_site);
            flash_dbg_print("nand block write reseek @ %04X, offset : %d", efat.wr_fil_block, addr_offset);
        }

        // aes mode
        if (efat.main_aes_mode == 0x55)
        {
            int site, len_rd;

            if (len + fil_site < efat.main_len)
            {
                len_rd = len;
            }
            else
            {
                len_rd = efat.main_len - fil_site;
            }

            efat.fst = fat_fil_read(efat.fil, efat.buff, len, &len_back);

            // decode
            for (site = 0; site < len_back; site += 16)
            {
                mbedtls_aes_crypt_ecb(efat.aes_obj, MBEDTLS_AES_DECRYPT, &efat.buff[site], &(pdat[site]));
                if (efat.sha_en)
                    mbedtls_sha256_update(efat.sha_obj, &pdat[site], 16);
                if (efat.md5_en)
                    mbedtls_md5_update(efat.md5_obj, &pdat[site], 16);
            }
        }
        // nor mode
        else
        {
            // read data
            efat.fst = fat_fil_read(efat.fil, pdat, len, &len_back);

            if (efat.sha_en)
                mbedtls_sha256_update(efat.sha_obj, pdat, len_back);
            if (efat.md5_en)
                mbedtls_md5_update(efat.md5_obj, pdat, len_back);
        }

        if (len_back < len)
        {
            set_u8(&pdat[len_back], 0xFF, len - len_back);
        }

        efat.wr_site_old = fil_site;
    }
    else
    {
        set_u8(pdat, 0xFF, len);
    }

    return 0;
}
